package com.anxin.act.task.complete.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.anxin.act.task.complete.TaskComplete;
import com.anxin.act.task.dao.WfActHiTaskDao;
import com.anxin.act.task.entity.WfActHiTask;
import com.anxin.act.task.entity.WfActRuTask;
import com.anxin.act.task.service.*;
import com.anxin.act.task.vo.TaskVo;
import com.anxin.act.utils.ActTaskUtils;
import com.anxin.act.utils.ActUtils;
import com.anxin.common.utils.dict.DictUtils;
import com.anxin.common.utils.sys.UserUtils;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 驳回提交
 * @author: 刘翔宇
 * @date: 2020/4/26 16:22
 */
@Service
public class RejectedCompleteImpl extends TaskComplete {

    @Autowired
    private JumpTaskService jumpTaskService;
    @Autowired
    private WfActHiCommentService wfActHiCommentService;
    @Autowired
    private WfActHiTaskDao wfActHiTaskDao;
    @Autowired
    private WfActRuTaskService wfActRuTaskService;
    @Autowired
    private WfActHiTaskService wfActHiTaskService;
    @Autowired
    private AddTaskService addTaskService;


    /**
     * 提交流程
     *
     * 提交方式
     * 按正常流程审批：normal
     * 直接提交至当前节点:current
     *
     * @param taskVo
     */
    public String complete(TaskVo taskVo){

        String taskId = taskVo.getId();

        // 驳回后正常提交
        if ("actTask".equals(taskVo.getViewRuTask().getType())) {
            this.rejectedActTask(taskVo);
        } else {
            // 前加签任务驳回至当前节点时任务直接回到前加签节点
            if ("current".equals(taskVo.getRejectedCompleteType()) && "addBefore".equals(taskVo.getViewRuTask().getType())) {
                taskId = this.rejectedAddTaskCurrent(taskVo);
            } else {
                this.rejectedAddTask(taskVo);
            }
        }


        // 签收任务
        ActTaskUtils.claimTask(taskVo.getActId());

        // 跳过节点
        jumpTaskService.jumpTask(taskVo.getActId(),taskVo.getId());

        return taskId;

    }

    /**
     * 驳回前加签等任务-驳回后提交至当前节点
     * @param taskVo
     */
    public String rejectedAddTaskCurrent(TaskVo taskVo){
        ActivityImpl activityImpl = ActUtils.getActivityImpl(taskVo.getProcessDefId(), taskVo.getRejectedNode());
        // 节点名称
        String nodeName = activityImpl.getProperty("name").toString();
        // 是否可以修改表单
        String actmodifyForm = (activityImpl.getProperty("actmodifyfrom") != null && "true".equals(activityImpl.getProperty("actmodifyfrom").toString())) ? "Y" : "N";
        // 获取节点审批人
        List<String> assigneeList = ActTaskUtils.getAssigneeList(taskVo.getActId(), taskVo.getRejectedNode());

        // 保存当前任务的审批记录
        WfActHiTask wfActHiTask = wfActHiCommentService.getHiTask(taskVo);
        wfActHiTaskService.save(wfActHiTask);

        wfActHiCommentService.addComment(taskVo,wfActHiTask.getId());
        wfActHiCommentService.addComment(taskVo.getActId(),wfActHiTask.getId(), "驳回提交方式:"+ DictUtils.getDictLabel(taskVo.getRejectedCompleteType(),"rejected_submit_method",""));


        // 进行前加签
        taskVo.setCompleteType("addBefore");
        taskVo.setAddTaskModifyFrom(actmodifyForm);
        taskVo.setNewTaskName(nodeName);
        // 设置节点人
        taskVo.setAddUser(JSONArray.parseArray(JSON.toJSONString(assigneeList)));

        wfActRuTaskService.addTask(taskVo);
        // 挂起流程
        addTaskService.hangTask(taskVo.getViewRuTask());

        return wfActHiTask.getId();

    }


    /**
     * 驳回Activity任务
     * 正常驳回：直接跳转节点
     * 驳回后回到当前节点：驳回后为任务增加变量
     *  rejectedCompleteNode:驳回任务提交至那个节点,actTask时为节点的Key,addTask时为节点的ID
     *  rejectedCompleteNodeType:驳回后提交的节点类型 actTask,addTask
     * @param taskVo
     */
    public void rejectedActTask(TaskVo taskVo){
        super.addComment(taskVo,"驳回提交方式:"+ DictUtils.getDictLabel(taskVo.getRejectedCompleteType(),"rejected_submit_method",""));
        // 保存审批意见
        super.addComment(taskVo);

        jumpTaskService.jumpTask(taskVo.getActId(), taskVo.getTaskId(),taskVo.getRejectedNode(), new HashMap<>());

        List<Task> taskList = ActTaskUtils.getTaskList(taskVo.getRejectedNode(), taskVo.getActId());
        for (Task task : taskList) {
            taskService.setVariableLocal(task.getId(), "rejectedCompleteType", taskVo.getRejectedCompleteType());
            taskService.setVariableLocal(task.getId(), "rejectedCompleteNodeType", "actTask");
            taskService.setVariableLocal(task.getId(), "rejectedCompleteNode", taskVo.getTaskKey());
            taskService.setVariableLocal(task.getId(),"rejectedCompleteTaskId",taskVo.getId());
        }

    }

    /**
     * 驳回加签任务
     * @param taskVo
     */
    public void rejectedAddTask(TaskVo taskVo){
        // 保存审批意见
        wfActHiTaskDao.complete(new WfActHiTask(taskVo.getId()));

        wfActHiCommentService.addComment(taskVo,taskVo.getId());
        wfActHiCommentService.addComment(taskVo.getActId(),taskVo.getId(),"驳回提交方式:"+ DictUtils.getDictLabel(taskVo.getRejectedCompleteType(),"rejected_submit_method",""));




        WfActRuTask wfActRuTask = wfActRuTaskService.get(taskVo.getId());

        jumpTaskService.jumpTask(taskVo.getActId(), taskVo.getTaskId(),taskVo.getRejectedNode(), new HashMap<>());

        // 正常驳回
        List<Task> taskList = ActTaskUtils.getTaskList(taskVo.getRejectedNode(), wfActRuTask.getActId());
        for (Task task : taskList) {
            taskService.setVariableLocal(task.getId(), "rejectedCompleteType", taskVo.getRejectedCompleteType());
            taskService.setVariableLocal(task.getId(), "rejectedCompleteNodeType", "actTask");
            taskService.setVariableLocal(task.getId(), "rejectedCompleteNode", taskVo.getTaskKey());
            taskService.setVariableLocal(task.getId(), "rejectedCompleteTaskId", taskVo.getId());
        }

        // 删除待办
        wfActRuTaskService.delBySourceId(wfActRuTask.getSourceId());

    }


}
